library(beeswarm)
library(data.table)
library(dichromat)
library(dplyr)
library(factoextra)
library(fmsb)
library(ggplot2)
library(gridExtra)
library(qdap)
library(RANN)
library(RColorBrewer)
library(readtext)
library(rvest)
library(scales)
library(sentimentr)
library(stopwords)
library(stringr)
library(syuzhet)
library(textreuse)
library(tibble)
library(tidytext)
library(tidyverse)
library(tm)
library(topicmodels)
library(wesanderson)
library(wordcloud)
source("../lib/plot_stacked.R")
source("../lib/speech_funcs.R")
source("../lib/helper_funcs.R")
# df <- read.csv("../data/philosophy_data.csv")

# Read data using data.table to decrease runtime
df <- data.table::fread("../output/philosophy_data_table.csv")

df <- df %>%
  group_by(school) %>%
  mutate(mode_date = find_mode(original_publication_date)) %>%
  ungroup() %>%
  mutate(school = ifelse(school == "german_idealism", "German Idealism", str_to_title(school)),
         school_ordered = reorder(factor(school), mode_date, mean, order = TRUE))

palette <- get_palette(length(unique(df$school)))

Overview

par(mfrow = c(4, 4))
i <- 0
for(s in levels(df$school_ordered)) {
  docs <- Corpus(VectorSource(df[df$school == s, ]$sentence_str)) %>%
    tm_map(tolower) %>%
    tm_map(removePunctuation) %>%
    tm_map(removeNumbers) %>%
    tm_map(removeWords, stopwords("english")) %>%
    tm_map(stripWhitespace)
  
  tdm <- TermDocumentMatrix(docs)
  tdm_tidy <- tidy(tdm)
  tdm_overall <- summarise(group_by(tdm_tidy, term), sum(count))
  
  i <- i + 1
  plt_title <- s
  wordcloud(tdm_overall$term, tdm_overall$`sum(count)`,
            scale = c(5, 0.5),
            max.words = 200,
            min.freq = 1,
            random.order = FALSE,
            rot.per = 0.3,
            random.color = FALSE,
            colors = palette[i])
  mtext(plt_title, side = 3)
}

df %>%
  unnest_tokens(bigram, sentence_str, token = "ngrams", n = 2) %>%
  separate(bigram, c("word1", "word2"), sep = " ") %>%
  filter(!word1 %in% stopwords::stopwords(source = "snowball")) %>%
  filter(!word2 %in% stopwords::stopwords(source = "snowball")) %>%
  filter(!is.na(word1)) %>%
  filter(!is.na(word2)) %>%
  unite(bigram, word1, word2, sep = " ") %>%
  group_by(school_ordered, bigram) %>%
  summarize(n_bigram = n()) %>%
  slice_max(n_bigram, n = 10) %>%
  mutate(bigram = reorder_within(bigram, n_bigram, school_ordered)) %>%
  ggplot(aes(x = bigram, y = n_bigram, fill = school_ordered)) +
  geom_bar(stat = "identity", show.legend = FALSE) +
  facet_wrap(~school_ordered, scales = "free") +
  coord_flip() +
  scale_x_reordered() +
  scale_fill_manual(values = get_palette(length(unique(df$school)))) +
  labs(title = "Top 10 Bigrams by School", x = element_blank(), y = "Count") +
  theme_classic()

Philosophy speech

df %>%
  ggplot(aes(x = sentence_length, fill = school_ordered)) +
  geom_histogram(binwidth = 2, size = 0.25, show.legend = FALSE) +
  xlim(0, 500) +
  facet_grid(rows = vars(school_ordered)) +
  scale_fill_manual(values = palette) +
  labs(title = "Sentence Length by School", x = "Word count", y = "Sentence count") +
  theme_classic()

Sentiment analysis

emotions <- data.table::fread("../output/emotions.csv")
df_emotions <- cbind(df, emotions)
par(mfrow = c(4, 4))
i <- 0
for(s in levels(df$school_ordered)) {
  emotions_by_school <- df_emotions %>%
    mutate(school = ifelse(school == "german_idealism", "German Idealism", str_to_title(school))) %>%
    filter(school == s) %>%
    dplyr::select(anger, anticipation, disgust, fear, joy, sadness, surprise, trust) %>%
    bind_rows(summarise_all(., ~if(is.numeric(.)) sum(.) else "Total")) %>%
    slice_tail(n = 1) %>%
    as.data.frame()
  emotions_by_school <- rbind(rep(max(emotions_by_school), 8), rep(min(emotions_by_school), 8), emotions_by_school)
  
  i <- i + 1
  plt_title <- s
  radarchart(emotions_by_school, title = plt_title,
           pcol = palette[i], pfcol = alpha(palette[i], 0.3), plwd = 2,
           cglcol = "grey", cglty = 1, axislabcol = "grey", caxislabels = seq(0,20,5))
}

Similarity analysis

LS0tCnRpdGxlOiAiUHJvamVjdCAxOiBIaXN0b3J5IG9mIFBoaWxvc29waHkiCmF1dGhvcjogIktpZXUtR2lhbmcgTmd1eWVuIgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCgpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KbGlicmFyeShiZWVzd2FybSkKbGlicmFyeShkYXRhLnRhYmxlKQpsaWJyYXJ5KGRpY2hyb21hdCkKbGlicmFyeShkcGx5cikKbGlicmFyeShmYWN0b2V4dHJhKQpsaWJyYXJ5KGZtc2IpCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShncmlkRXh0cmEpCmxpYnJhcnkocWRhcCkKbGlicmFyeShxdWFudGVkYSkKbGlicmFyeShxdWFudGVkYS50ZXh0c3RhdHMpCmxpYnJhcnkoUkFOTikKbGlicmFyeShSQ29sb3JCcmV3ZXIpCmxpYnJhcnkocmVhZHRleHQpCmxpYnJhcnkocnZlc3QpCmxpYnJhcnkoc2NhbGVzKQpsaWJyYXJ5KHNlbnRpbWVudHIpCmxpYnJhcnkoc3RvcHdvcmRzKQpsaWJyYXJ5KHN0cmluZ3IpCmxpYnJhcnkoc3l1emhldCkKbGlicmFyeSh0ZXh0cmV1c2UpCmxpYnJhcnkodGliYmxlKQpsaWJyYXJ5KHRpZHl0ZXh0KQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeSh0bSkKbGlicmFyeSh0b3BpY21vZGVscykKbGlicmFyeSh3ZXNhbmRlcnNvbikKbGlicmFyeSh3b3JkY2xvdWQpCgpzb3VyY2UoIi4uL2xpYi9wbG90X3N0YWNrZWQuUiIpCnNvdXJjZSgiLi4vbGliL3NwZWVjaF9mdW5jcy5SIikKc291cmNlKCIuLi9saWIvaGVscGVyX2Z1bmNzLlIiKQpgYGAKCmBgYHtyLCBldmFsPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQojIGRmIDwtIHJlYWQuY3N2KCIuLi9kYXRhL3BoaWxvc29waHlfZGF0YS5jc3YiKQoKIyBSZWFkIGRhdGEgdXNpbmcgZGF0YS50YWJsZSB0byBkZWNyZWFzZSBydW50aW1lCmRmIDwtIGRhdGEudGFibGU6OmZyZWFkKCIuLi9vdXRwdXQvcGhpbG9zb3BoeV9kYXRhX3RhYmxlLmNzdiIpCgpkZiA8LSBkZiAlPiUKICBncm91cF9ieShzY2hvb2wpICU+JQogIG11dGF0ZShtb2RlX2RhdGUgPSBmaW5kX21vZGUob3JpZ2luYWxfcHVibGljYXRpb25fZGF0ZSkpICU+JQogIHVuZ3JvdXAoKSAlPiUKICBtdXRhdGUoc2Nob29sID0gaWZlbHNlKHNjaG9vbCA9PSAiZ2VybWFuX2lkZWFsaXNtIiwgIkdlcm1hbiBJZGVhbGlzbSIsIHN0cl90b190aXRsZShzY2hvb2wpKSwKICAgICAgICAgc2Nob29sX29yZGVyZWQgPSByZW9yZGVyKGZhY3RvcihzY2hvb2wpLCBtb2RlX2RhdGUsIG1lYW4sIG9yZGVyID0gVFJVRSkpCgpwYWxldHRlIDwtIGdldF9wYWxldHRlKGxlbmd0aCh1bmlxdWUoZGYkc2Nob29sKSkpCmBgYAoKIyBPdmVydmlldwoKYGBge3IsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGZpZy53aWR0aD02LCBmaWcuaGVpZ2h0PTZ9CnBhcihtZnJvdyA9IGMoNCwgNCkpCgppIDwtIDAKZm9yKHMgaW4gbGV2ZWxzKGRmJHNjaG9vbF9vcmRlcmVkKSkgewogIGRvY3MgPC0gQ29ycHVzKFZlY3RvclNvdXJjZShkZltkZiRzY2hvb2wgPT0gcywgXSRzZW50ZW5jZV9zdHIpKSAlPiUKICAgIHRtX21hcCh0b2xvd2VyKSAlPiUKICAgIHRtX21hcChyZW1vdmVQdW5jdHVhdGlvbikgJT4lCiAgICB0bV9tYXAocmVtb3ZlTnVtYmVycykgJT4lCiAgICB0bV9tYXAocmVtb3ZlV29yZHMsIHN0b3B3b3JkcygiZW5nbGlzaCIpKSAlPiUKICAgIHRtX21hcChzdHJpcFdoaXRlc3BhY2UpCiAgCiAgdGRtIDwtIFRlcm1Eb2N1bWVudE1hdHJpeChkb2NzKQogIHRkbV90aWR5IDwtIHRpZHkodGRtKQogIHRkbV9vdmVyYWxsIDwtIHN1bW1hcmlzZShncm91cF9ieSh0ZG1fdGlkeSwgdGVybSksIHN1bShjb3VudCkpCiAgCiAgaSA8LSBpICsgMQogIHBsdF90aXRsZSA8LSBzCiAgd29yZGNsb3VkKHRkbV9vdmVyYWxsJHRlcm0sIHRkbV9vdmVyYWxsJGBzdW0oY291bnQpYCwKICAgICAgICAgICAgc2NhbGUgPSBjKDUsIDAuNSksCiAgICAgICAgICAgIG1heC53b3JkcyA9IDIwMCwKICAgICAgICAgICAgbWluLmZyZXEgPSAxLAogICAgICAgICAgICByYW5kb20ub3JkZXIgPSBGQUxTRSwKICAgICAgICAgICAgcm90LnBlciA9IDAuMywKICAgICAgICAgICAgcmFuZG9tLmNvbG9yID0gRkFMU0UsCiAgICAgICAgICAgIGNvbG9ycyA9IHBhbGV0dGVbaV0pCiAgbXRleHQocGx0X3RpdGxlLCBzaWRlID0gMykKfQpgYGAKCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBmaWcud2lkdGg9NiwgZmlnLmhlaWdodD02fQpkZiAlPiUKICB1bm5lc3RfdG9rZW5zKGJpZ3JhbSwgc2VudGVuY2Vfc3RyLCB0b2tlbiA9ICJuZ3JhbXMiLCBuID0gMikgJT4lCiAgc2VwYXJhdGUoYmlncmFtLCBjKCJ3b3JkMSIsICJ3b3JkMiIpLCBzZXAgPSAiICIpICU+JQogIGZpbHRlcighd29yZDEgJWluJSBzdG9wd29yZHM6OnN0b3B3b3Jkcyhzb3VyY2UgPSAic25vd2JhbGwiKSkgJT4lCiAgZmlsdGVyKCF3b3JkMiAlaW4lIHN0b3B3b3Jkczo6c3RvcHdvcmRzKHNvdXJjZSA9ICJzbm93YmFsbCIpKSAlPiUKICBmaWx0ZXIoIWlzLm5hKHdvcmQxKSkgJT4lCiAgZmlsdGVyKCFpcy5uYSh3b3JkMikpICU+JQogIHVuaXRlKGJpZ3JhbSwgd29yZDEsIHdvcmQyLCBzZXAgPSAiICIpICU+JQogIGdyb3VwX2J5KHNjaG9vbF9vcmRlcmVkLCBiaWdyYW0pICU+JQogIHN1bW1hcml6ZShuX2JpZ3JhbSA9IG4oKSkgJT4lCiAgc2xpY2VfbWF4KG5fYmlncmFtLCBuID0gMTApICU+JQogIG11dGF0ZShiaWdyYW0gPSByZW9yZGVyX3dpdGhpbihiaWdyYW0sIG5fYmlncmFtLCBzY2hvb2xfb3JkZXJlZCkpICU+JQogIGdncGxvdChhZXMoeCA9IGJpZ3JhbSwgeSA9IG5fYmlncmFtLCBmaWxsID0gc2Nob29sX29yZGVyZWQpKSArCiAgICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5Iiwgc2hvdy5sZWdlbmQgPSBGQUxTRSkgKwogICAgZmFjZXRfd3JhcCh+c2Nob29sX29yZGVyZWQsIHNjYWxlcyA9ICJmcmVlIikgKwogICAgY29vcmRfZmxpcCgpICsKICAgIHNjYWxlX3hfcmVvcmRlcmVkKCkgKwogICAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gZ2V0X3BhbGV0dGUobGVuZ3RoKHVuaXF1ZShkZiRzY2hvb2wpKSkpICsKICAgIGxhYnModGl0bGUgPSAiVG9wIDEwIEJpZ3JhbXMgYnkgU2Nob29sIiwgeCA9IGVsZW1lbnRfYmxhbmsoKSwgeSA9ICJDb3VudCIpICsKICAgIHRoZW1lX2NsYXNzaWMoKQpgYGAKCiMgUGhpbG9zb3BoeSBzcGVlY2gKCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBmaWcud2lkdGg9NiwgZmlnLmhlaWdodD02fQpkZiAlPiUKICBnZ3Bsb3QoYWVzKHggPSBzZW50ZW5jZV9sZW5ndGgsIGZpbGwgPSBzY2hvb2xfb3JkZXJlZCkpICsKICAgIGdlb21faGlzdG9ncmFtKGJpbndpZHRoID0gMiwgc2l6ZSA9IDAuMjUsIHNob3cubGVnZW5kID0gRkFMU0UpICsKICAgIHhsaW0oMCwgNTAwKSArCiAgICBmYWNldF9ncmlkKHJvd3MgPSB2YXJzKHNjaG9vbF9vcmRlcmVkKSkgKwogICAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gcGFsZXR0ZSkgKwogICAgbGFicyh0aXRsZSA9ICJTZW50ZW5jZSBMZW5ndGggYnkgU2Nob29sIiwgeCA9ICJXb3JkIGNvdW50IiwgeSA9ICJTZW50ZW5jZSBjb3VudCIpICsKICAgIHRoZW1lX2NsYXNzaWMoKQpgYGAKCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBmaWcud2lkdGg9NiwgZmlnLmhlaWdodD0zfQpkZl9hdmdfbGVuZ3RoIDwtIGRmICU+JQogIGdyb3VwX2J5KG9yaWdpbmFsX3B1YmxpY2F0aW9uX2RhdGUpICU+JQogIG11dGF0ZShhdmdfbGVuZ3RoX3RpbWUgPSByb3VuZChtZWFuKHNlbnRlbmNlX2xlbmd0aCksIDApKSAlPiUKICB1bmdyb3VwKCkgJT4lCiAgZ3JvdXBfYnkoc2Nob29sX29yZGVyZWQpICU+JQogIG11dGF0ZShhdmdfbGVuZ3RoX3NjaG9vbCA9IHJvdW5kKG1lYW4oc2VudGVuY2VfbGVuZ3RoKSwgMCkpICU+JQogIHVuZ3JvdXAoKSAlPiUKICBkaXN0aW5jdChvcmlnaW5hbF9wdWJsaWNhdGlvbl9kYXRlLCBzY2hvb2xfb3JkZXJlZCwgbW9kZV9kYXRlLCBhdmdfbGVuZ3RoX3RpbWUsIGF2Z19sZW5ndGhfc2Nob29sKQoKZ2dwbG90KCkgKwogIGdlb21fbGluZShkYXRhID0gZGZfYXZnX2xlbmd0aCwgYWVzKHggPSBvcmlnaW5hbF9wdWJsaWNhdGlvbl9kYXRlLCB5ID0gYXZnX2xlbmd0aF90aW1lKSwgc3RhdCA9ICJpZGVudGl0eSIpICsKICBnZW9tX2JhcihkYXRhID0gZGlzdGluY3QoZGZfYXZnX2xlbmd0aCwgc2Nob29sX29yZGVyZWQsIG1vZGVfZGF0ZSwgYXZnX2xlbmd0aF9zY2hvb2wpLCBhZXMoeCA9IG1vZGVfZGF0ZSwgeSA9IGF2Z19sZW5ndGhfc2Nob29sLCBmaWxsID0gc2Nob29sX29yZGVyZWQpLCBzdGF0ID0gImlkZW50aXR5Iiwgd2lkdGggPSA1KSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gcGFsZXR0ZSkgKwogIGxhYnModGl0bGUgPSAiQXZlcmFnZSBTZW50ZW5jZSBMZW5ndGgiLCB4ID0gIlllYXIiLCB5ID0gIldvcmQgY291bnQiLCBmaWxsID0gIlNjaG9vbCIpICsKICB0aGVtZV9jbGFzc2ljKCkgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iLCBsZWdlbmQuZGlyZWN0aW9uID0gImhvcml6b250YWwiKQpgYGAKCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBmaWcud2lkdGg9NiwgZmlnLmhlaWdodD0zfQpkZl9kaXN0aW5jdF93b3JkIDwtIGRmICU+JQogIHVubmVzdF90b2tlbnMod29yZCwgc2VudGVuY2Vfc3RyKSAlPiUKICBmaWx0ZXIoISh3b3JkICVpbiUgc3RvcHdvcmRzOjpzdG9wd29yZHMoc291cmNlID0gInNub3diYWxsIikpKSAlPiUKICBncm91cF9ieShvcmlnaW5hbF9wdWJsaWNhdGlvbl9kYXRlKSAlPiUKICBtdXRhdGUobmRpc3RpbmN0X3dvcmRfdGltZSA9IGxlbmd0aCh1bmlxdWUod29yZCkpKSAlPiUKICB1bmdyb3VwKCkgJT4lCiAgZ3JvdXBfYnkoc2Nob29sX29yZGVyZWQpICU+JQogIG11dGF0ZShuZGlzdGluY3Rfd29yZF9zY2hvb2wgPSBsZW5ndGgodW5pcXVlKHdvcmQpKSkgJT4lCiAgdW5ncm91cCgpICU+JQogIGRpc3RpbmN0KG9yaWdpbmFsX3B1YmxpY2F0aW9uX2RhdGUsIHNjaG9vbF9vcmRlcmVkLCBtb2RlX2RhdGUsIG5kaXN0aW5jdF93b3JkX3RpbWUsIG5kaXN0aW5jdF93b3JkX3NjaG9vbCkKCmdncGxvdCgpICsKICBnZW9tX2xpbmUoZGF0YSA9IGRmX2Rpc3RpbmN0X3dvcmQsIGFlcyh4ID0gb3JpZ2luYWxfcHVibGljYXRpb25fZGF0ZSwgeSA9IG5kaXN0aW5jdF93b3JkX3RpbWUpLCBzdGF0ID0gImlkZW50aXR5IikgKwogIGdlb21fYmFyKGRhdGEgPSBkaXN0aW5jdChkZl9kaXN0aW5jdF93b3JkLCBzY2hvb2xfb3JkZXJlZCwgbW9kZV9kYXRlLCBuZGlzdGluY3Rfd29yZF9zY2hvb2wpLCBhZXMoeCA9IG1vZGVfZGF0ZSwgeSA9IG5kaXN0aW5jdF93b3JkX3NjaG9vbCwgZmlsbCA9IHNjaG9vbF9vcmRlcmVkKSwgc3RhdCA9ICJpZGVudGl0eSIsIHdpZHRoID0gNSkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IHBhbGV0dGUpICsKICBsYWJzKHRpdGxlID0gIk51bWJlciBvZiBEaXN0aW5jdCBXb3JkcyIsIHggPSAiWWVhciIsIHkgPSAiV29yZCBjb3VudCIsIGZpbGwgPSAiU2Nob29sIikgKwogIHRoZW1lX2NsYXNzaWMoKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIsIGxlZ2VuZC5kaXJlY3Rpb24gPSAiaG9yaXpvbnRhbCIpCmBgYAoKIyBTZW50aW1lbnQgYW5hbHlzaXMKCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQplbW90aW9ucyA8LSBkYXRhLnRhYmxlOjpmcmVhZCgiLi4vb3V0cHV0L2Vtb3Rpb25zLmNzdiIpCmRmX2Vtb3Rpb25zIDwtIGNiaW5kKGRmLCBlbW90aW9ucykKYGBgCgpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgZmlnLndpZHRoPTYsIGZpZy5oZWlnaHQ9Nn0KcGFyKG1mcm93ID0gYyg0LCA0KSkKCmkgPC0gMApmb3IocyBpbiBsZXZlbHMoZGYkc2Nob29sX29yZGVyZWQpKSB7CiAgZW1vdGlvbnNfYnlfc2Nob29sIDwtIGRmX2Vtb3Rpb25zICU+JQogICAgbXV0YXRlKHNjaG9vbCA9IGlmZWxzZShzY2hvb2wgPT0gImdlcm1hbl9pZGVhbGlzbSIsICJHZXJtYW4gSWRlYWxpc20iLCBzdHJfdG9fdGl0bGUoc2Nob29sKSkpICU+JQogICAgZmlsdGVyKHNjaG9vbCA9PSBzKSAlPiUKICAgIGRwbHlyOjpzZWxlY3QoYW5nZXIsIGFudGljaXBhdGlvbiwgZGlzZ3VzdCwgZmVhciwgam95LCBzYWRuZXNzLCBzdXJwcmlzZSwgdHJ1c3QpICU+JQogICAgYmluZF9yb3dzKHN1bW1hcmlzZV9hbGwoLiwgfmlmKGlzLm51bWVyaWMoLikpIHN1bSguKSBlbHNlICJUb3RhbCIpKSAlPiUKICAgIHNsaWNlX3RhaWwobiA9IDEpICU+JQogICAgYXMuZGF0YS5mcmFtZSgpCgogIGVtb3Rpb25zX2J5X3NjaG9vbCA8LSByYmluZChyZXAobWF4KGVtb3Rpb25zX2J5X3NjaG9vbCksIDgpLCByZXAobWluKGVtb3Rpb25zX2J5X3NjaG9vbCksIDgpLCBlbW90aW9uc19ieV9zY2hvb2wpCiAgCiAgaSA8LSBpICsgMQogIHBsdF90aXRsZSA8LSBzCiAgcmFkYXJjaGFydChlbW90aW9uc19ieV9zY2hvb2wsIHRpdGxlID0gcGx0X3RpdGxlLAogICAgICAgICAgIHBjb2wgPSBwYWxldHRlW2ldLCBwZmNvbCA9IGFscGhhKHBhbGV0dGVbaV0sIDAuMyksIHBsd2QgPSAyLAogICAgICAgICAgIGNnbGNvbCA9ICJncmV5IiwgY2dsdHkgPSAxLCBheGlzbGFiY29sID0gImdyZXkiLCBjYXhpc2xhYmVscyA9IHNlcSgwLDIwLDUpKQp9CmBgYAoKYGBge3IsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGZpZy53aWR0aD02LCBmaWcuaGVpZ2h0PTN9CiMgRGVmYXVsdCBjb2xvcnM6ICIjRjg3NjZEIiwgIiMwMEJGQzQiCmRmX2Vtb3Rpb25zICU+JQogIGdyb3VwX2J5KG9yaWdpbmFsX3B1YmxpY2F0aW9uX2RhdGUpICU+JQogIHN1bW1hcml6ZShwb3NpdGl2ZSA9IG1lYW4ocG9zaXRpdmUpLAogICAgICAgICAgICBuZWdhdGl2ZSA9IG1lYW4obmVnYXRpdmUpKSAlPiUKICBwaXZvdF9sb25nZXIoIW9yaWdpbmFsX3B1YmxpY2F0aW9uX2RhdGUsIG5hbWVzX3RvID0gImVtb3Rpb24iLCB2YWx1ZXNfdG8gPSAiYXZnX2NvdW50IikgJT4lCiAgZ2dwbG90KGFlcyh4ID0gb3JpZ2luYWxfcHVibGljYXRpb25fZGF0ZSwgeSA9IGF2Z19jb3VudCwgY29sb3IgPSBlbW90aW9uKSkgKwogICAgZ2VvbV9saW5lKHN0YXQgPSAiaWRlbnRpdHkiKSArCiAgICBsYWJzKHRpdGxlID0gIkVtb3Rpb25hbCBWYWxlbmNlIG92ZXIgVGltZSIsIHggPSAiWWVhciIsIHkgPSAiQXZlcmFnZSBjb3VudCIsIGNvbG9yID0gIkVtb3Rpb24iKSArCiAgICAjIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSB3ZXNfcGFsZXR0ZSgiUnVzaG1vcmUxIiwgOCwgdHlwZSA9ICJjb250aW51b3VzIikpICsKICAgIHRoZW1lX2NsYXNzaWMoKQpgYGAKCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBmaWcud2lkdGg9NiwgZmlnLmhlaWdodD0zfQpkZl9lbW90aW9ucyAlPiUKICBncm91cF9ieShvcmlnaW5hbF9wdWJsaWNhdGlvbl9kYXRlKSAlPiUKICBzdW1tYXJpemUoYW5nZXIgPSBtZWFuKGFuZ2VyKSwKICAgICAgICAgICAgYW50aWNpcGF0aW9uID0gbWVhbihhbnRpY2lwYXRpb24pLAogICAgICAgICAgICBkaXNndXN0ID0gbWVhbihkaXNndXN0KSwKICAgICAgICAgICAgZmVhciA9IG1lYW4oZmVhciksCiAgICAgICAgICAgIGpveSA9IG1lYW4oam95KSwKICAgICAgICAgICAgc2FkbmVzcyA9IG1lYW4oc2FkbmVzcyksCiAgICAgICAgICAgIHN1cnByaXNlID0gbWVhbihzdXJwcmlzZSksCiAgICAgICAgICAgIHRydXN0ID0gbWVhbih0cnVzdCkpICU+JQogIHBpdm90X2xvbmdlcighb3JpZ2luYWxfcHVibGljYXRpb25fZGF0ZSwgbmFtZXNfdG8gPSAiZW1vdGlvbiIsIHZhbHVlc190byA9ICJhdmdfY291bnQiKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSBvcmlnaW5hbF9wdWJsaWNhdGlvbl9kYXRlLCB5ID0gYXZnX2NvdW50LCBjb2xvciA9IGVtb3Rpb24pKSArCiAgICBnZW9tX2xpbmUoc3RhdCA9ICJpZGVudGl0eSIpICsKICAgIGxhYnModGl0bGUgPSAiU2VudGltZW50IG92ZXIgVGltZSIsIHggPSAiWWVhciIsIHkgPSAiQXZlcmFnZSBjb3VudCIsIGNvbG9yID0gIkVtb3Rpb24iKSArCiAgICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gd2VzX3BhbGV0dGUoIlJ1c2htb3JlMSIsIDgsIHR5cGUgPSAiY29udGludW91cyIpKSArCiAgICB0aGVtZV9jbGFzc2ljKCkKYGBgCgojIFNpbWlsYXJpdHkgYW5hbHlzaXMKCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBmaWcud2lkdGg9NiwgZmlnLmhlaWdodD0zfQpjb3JwX3NlbnRlbmNlIDwtIGNvcnB1cyhkZiwgdGV4dF9maWVsZCA9ICJzZW50ZW5jZV9zdHIiKQoKZGZtYXRfc2VudGVuY2UgPC0gY29ycF9zZW50ZW5jZSAlPiUKICBxdWFudGVkYTo6dG9rZW5zKHJlbW92ZV9wdW5jdCA9IFRSVUUsIHJlbW92ZV9zeW1ib2xzID0gVFJVRSkgJT4lIAogIGRmbSgpICU+JQogIGRmbV9yZW1vdmUocGF0dGVybiA9IHN0b3B3b3JkcygiZW4iKSkKCiMgZGZtYXRfYXV0aG9yIDwtIGRmbV9ncm91cChkZm1hdF9zZW50ZW5jZSwgZ3JvdXBzID0gYXV0aG9yKQojIHRzdGF0X2Rpc3QgPC0gYXMuZGlzdCh0ZXh0c3RhdF9kaXN0KGRmbWF0X2F1dGhvcikpCiMgYXV0aG9yX2NsdXN0IDwtIGhjbHVzdCh0c3RhdF9kaXN0KQojIHBsb3QoYXV0aG9yX2NsdXN0KQoKZGZtYXRfc2Nob29sIDwtIGRmbV9ncm91cChkZm1hdF9zZW50ZW5jZSwgZ3JvdXBzID0gc2Nob29sX29yZGVyZWQpCnRzdGF0X2Rpc3QgPC0gYXMuZGlzdCh0ZXh0c3RhdF9kaXN0KGRmbWF0X3NjaG9vbCkpCnNjaG9vbF9jbHVzdCA8LSBoY2x1c3QodHN0YXRfZGlzdCkKcGxvdChzY2hvb2xfY2x1c3QpCmBgYAoKYGBge3IsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGZpZy53aWR0aD02LCBmaWcuaGVpZ2h0PTN9CmVtb3Rpb25zX2J5X3NjaG9vbCA8LSBkZl9lbW90aW9ucyAlPiUKICBncm91cF9ieShzY2hvb2xfb3JkZXJlZCkgJT4lCiAgc3VtbWFyaXplKAogICAgYW5nZXIgPSBtZWFuKGFuZ2VyKSwKICAgIGFudGljaXBhdGlvbiA9IG1lYW4oYW50aWNpcGF0aW9uKSwKICAgIGRpc2d1c3QgPSBtZWFuKGRpc2d1c3QpLAogICAgZmVhciA9IG1lYW4oZmVhciksCiAgICBqb3kgPSBtZWFuKGpveSksCiAgICBzYWRuZXNzID0gbWVhbihzYWRuZXNzKSwKICAgIHN1cnByaXNlID0gbWVhbihzdXJwcmlzZSksCiAgICB0cnVzdCA9IG1lYW4odHJ1c3QpCiAgKSAlPiUKICBhcy5kYXRhLmZyYW1lKCkKCnJvd25hbWVzKGVtb3Rpb25zX2J5X3NjaG9vbCkgPC0gYXMuY2hhcmFjdGVyKChlbW90aW9uc19ieV9zY2hvb2xbLCAxXSkpCmttZWFuc19yZXMgPC0ga21lYW5zKGVtb3Rpb25zX2J5X3NjaG9vbFssLTFdLCBpdGVyLm1heCA9IDIwMCwgNSkKZnZpel9jbHVzdGVyKGttZWFuc19yZXMsIHN0YW5kID0gRkFMU0UsIHJlcGVsID0gVFJVRSwKICAgICAgICAgICAgIGRhdGEgPSBlbW90aW9uc19ieV9zY2hvb2xbLC0xXSwgeGxhYiA9ICIiLCB4YXh0ID0gIm4iLAogICAgICAgICAgICAgc2hvdy5jbHVzdC5jZW50ID0gRkFMU0UsIGdndGhlbWUgPSB0aGVtZV9jbGFzc2ljKCkpCmBgYA==